package com.easy.base.service.impl;

import java.util.List;

import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import com.easy.base.domain.EObject;
import com.easy.common.jdbc.DymaticCondition;
import com.easy.common.jdbc.PageInfo;
import com.easy.common.util.BeanUtil;
import com.easy.common.util.DateUtil;
import com.easy.common.util.SqlUtil;
import com.easy.common.web.PagedList;

public class EManagerImpl<T extends EObject> extends JdbcDaoSupport {

	public static Logger logger = Logger.getLogger(EManagerImpl.class);

	@Autowired
	public void setSuperDataSource(DataSource dataSource) {
		setDataSource(dataSource);
	}

	/**
	 * 插入或保存一条记录
	 * 
	 * @param t
	 *            记录对象
	 * @return 数据库中记录更改的数量
	 */
	public int saveOrEdit(T t) {
		String lmt = t.getLast_modify_time();
		if (lmt == null || "".equals(lmt)) {
			t.setLast_modify_time(DateUtil.getSystemTime());
		}else{
			t.setLast_modify_time(DateUtil.getSystemDate());
		}

		if (findByOid(t) == null) {
			return save(t);
		}

		return edit(t);
	}

	/**
	 * 保存一条记录
	 * 
	 * @param t
	 * @return
	 */
	public int save(T t) {
		return update(SqlUtil.getInsertSql(t));
	}

	/**
	 * 更新一条记录
	 * 
	 * @param t
	 * @return
	 */
	public int edit(T t) {
		return update(SqlUtil.getUpdateSql(t));
	}

	/**
	 * 删除一条记录
	 * 
	 * @param t
	 * @return
	 */
	public int remove(T t) {
		return update(SqlUtil.getDeleteSql(t));
	}

	/**
	 * 批量删除
	 * 
	 * @param lt
	 * @return
	 */
	public int removeAll(List<T> lt) {
		int count = 0;
		for (T t : lt) {
			count += remove(t);
		}
		return count;
	}

	/**
	 * 根据OID搜索一条记录
	 * 
	 * @param o
	 *            搜索参数
	 * @return 搜索记录结果
	 */
	@SuppressWarnings("unchecked")
	public T findByOid(T o) {
		return queryOne(SqlUtil.getSelectByIdSql(o), null,
				new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(this, 0)));
	}

	/**
	 * 查询一条记录 （查询的条件要满足唯一性约束）
	 * 
	 * @param o
	 * @return
	 */
	public T find(T o) {
		List<T> list = findList(o);
		return list.size() != 0 ? list.get(0) : null;
	}

	/**
	 * 搜索符合条件的记录集合
	 * 
	 * @param t
	 *            搜索参数
	 * @return 要查询的结果集
	 */
	@SuppressWarnings("unchecked")
	public List<T> findList(T t) {
		return queryList(SqlUtil.getSelectAllEqualValueSql(t), null,
				new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(this, 0)));
	}

	/**
	 * 模糊查询符合条件的记录集合（有分页功能）
	 * 
	 * @param t
	 *            搜索条件参数
	 * @param pageInfo
	 *            分页参数
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	public PagedList<T> findAllLike(T t, PageInfo pageInfo) {
		return query(SqlUtil.getSelectAllLikeValueSql(t), null,
				new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(this, 0)),
				pageInfo);
	}

	/**
	 * 搜索符合条件的记录集合
	 * 
	 * @param t
	 *            搜索条件参数
	 * @param pageInfo
	 *            分页参数
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	public PagedList<T> findAllEqual(T t, PageInfo pageInfo) {
		return query(SqlUtil.getSelectAllEqualValueSql(t), null,
				new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(this, 0)),
				pageInfo);
	}

	/**
	 * 查询数据表中所有列的值包含text的记录
	 * 
	 * @param text
	 *            查询参数
	 * @param pageInfo
	 *            分页参数
	 * @return 查询结果集
	 */
	@SuppressWarnings("unchecked")
	public PagedList<T> findAllLikeText(String text, PageInfo pageInfo) {
		T t = null;
		try {
			Class<T> clazz = BeanUtil.getGenericType(this, 0);
			t = clazz.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return query(SqlUtil.getSelectAllLikeTextSql(t, text), null,
				new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(this, 0)),
				pageInfo);
	}

	protected int update(SqlUtil.SqlInfo info) {
		return update(info.getSql(), (Object[]) info.getValues());
	}

	protected int update(String sql, Object... args) throws DataAccessException {
		logger.debug("updateSql:[" + this.getClass().getName() + "]"
				+ getPreparedStatementSql(sql, args));

		return getJdbcTemplate().update(sql, args);
	}

	protected int update(String sql) throws DataAccessException {
		logger.debug("updateSql:[" + this.getClass().getName() + "]" + sql);

		return getJdbcTemplate().update(sql);
	}

	@SuppressWarnings("hiding")
	protected <T extends Object> T queryOne(String sql,
			DymaticCondition dymaticCondition, RowMapper<T> rowMapper) {
		if (dymaticCondition != null) {
			sql += dymaticCondition.toString();
		}

		logger.debug("querySql:[" + this.getClass().getName() + "]" + sql);

		try {
			return getJdbcTemplate().queryForObject(sql, rowMapper);
		} catch (EmptyResultDataAccessException e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings("hiding")
	protected <T extends Object> PagedList<T> query(String sql,
			DymaticCondition dymaticCondition, RowMapper<T> rowMapper,
			PageInfo info) {

		if (dymaticCondition == null) {
			dymaticCondition = new DymaticCondition();
		}
		if (info.getPage()<=0) {
			info.setPage(1);
		}
		return this.query(
				sql,
				dymaticCondition.addCondition("ORDER BY {0} {1}",
						info.getSort(), info.getOrder()), rowMapper,
				String.valueOf((info.getPage() - 1) * info.getRows()),
				String.valueOf(info.getRows()));
	}

	@SuppressWarnings({ "deprecation", "hiding" })
	protected <T extends Object> PagedList<T> query(String sql,
			DymaticCondition dymaticCondition, RowMapper<T> rowMapper,
			String start, String offset) {

		List<T> list = null;
		if (dymaticCondition != null) {
			sql += dymaticCondition.toString();
		}
		int total = getJdbcTemplate().queryForInt(getCountSql(sql));

		// Oracle 分页
		// if (sql != null && offset != null) {
		// sql = "SELECT * FROM (SELECT A.*, rownum rn FROM (" + sql
		// + ") A WHERE rownum <= "
		// + (Integer.parseInt(start) + Integer.parseInt(offset))
		// + " )WHERE rn > " + start;
		// }
		// MySql 分页/////////////////////////////////////////
		sql += new DymaticCondition().addCondition(" LIMIT {0}, {1}", start,
				offset).toString();
		// MySql 分页/////////////////////////////////////////

		logger.debug("querySql:[" + this.getClass().getName() + "]" + sql);
		list = getJdbcTemplate().query(sql, rowMapper);
		return new PagedList<T>(total, list);
	}

	@SuppressWarnings("hiding")
	protected <T extends Object> List<T> queryList(String sql,
			DymaticCondition dymaticCondition, RowMapper<T> rowMapper) {

		if (dymaticCondition != null) {
			sql += dymaticCondition.toString();
		}

		logger.debug("querySql:[" + this.getClass().getName() + "]" + sql);
		return getJdbcTemplate().query(sql, rowMapper);
	}

	private String getCountSql(String sql) {
		String sqlTmp = sql.toUpperCase();
		int index = sqlTmp.indexOf("FROM");

		return "SELECT count(*) " + sql.substring(index);
	}

	private String getPreparedStatementSql(String sql, Object... args) {
		if (args == null || args.length == 0) {
			return sql;
		}

		int index = -1;
		int i = 0;
		int size = args.length;

		StringBuffer buffer = new StringBuffer(sql);

		while ((index = sql.indexOf("?")) != -1 && (i < size)) {
			buffer.replace(index, index + 1, "'" + args[i++] + "'");
			sql = buffer.toString();
		}

		return buffer.toString();
	}
	
	@SuppressWarnings("unchecked")
	protected   List<T> findAllListNoParam(T t) {
		String sql="SELECT * FROM "+t.getClass().getSimpleName();	
		List<T> reportList= queryList(sql, null,new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(t, 0))	);
		return reportList;
	}

	/**
	 * 根据数据表格设置的过滤条件查询分页数据
	 * @param t
	 * @param pageInfo
	 * @return 分页数据列表
	 */
	@SuppressWarnings("unchecked")
	public PagedList<T> findByDynamicFilterCondition(T t, PageInfo pageInfo) {
		PagedList<T> pagedList = query(
				SqlUtil.getConditionsByOptions(t, pageInfo.getFilterRules()),
				null,
				new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(this, 0)),
				pageInfo);
		return pagedList;
	}
	/**
	 * 根据数据表格设置的过滤条件查询数据
	 * @param t
	 * @param List
	 * @return 数据列表
	 */
	@SuppressWarnings("unchecked")
	public PagedList<T> findListByDynamicFilterCondition(T t, PageInfo pageInfo) {
		PagedList<T> list = queryList(
				SqlUtil.getConditionsByOptions(t, pageInfo.getFilterRules()),
				null,
				new BeanPropertyRowMapper<T>(BeanUtil.getGenericType(this, 0)),
				pageInfo);
		
		return list;
	}
	
	
	@SuppressWarnings("hiding")
	protected <T extends Object> PagedList<T> queryList(String sql,
			DymaticCondition dymaticCondition, RowMapper<T> rowMapper,
			PageInfo info) {

		if (dymaticCondition == null) {
			dymaticCondition = new DymaticCondition();
		}

		return this.query(
				sql,
				dymaticCondition.addCondition("ORDER BY {0} {1}",
						info.getSort(), info.getOrder()), rowMapper,
				null,
				null);
	}
}
